import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/****************************************************\
 Author Info:
        Name: 左汇洁         Author ID: 202212702            Class: 2022187            School: NCWU
        Email: 2928866205@qq.com           Tel.13283038734
        Copyright (c) 2024 NCWU
 Module Name:
        Addition and subtraction oral arithmetic practice system
 Abstract:
        This module is used to neatly generate 50 non-repetitive addition and
        subtraction oral arithmetic problems up to 100 with answers
 Notes:
        None
 History:
        Created on 2024/9/22 by 2928866205@qq.com
 \****************************************************/

public class MathExercises05 {

    private int exerciseCount;  // 要生成的练习题数量
    private int maxNumber;  //习题中涉及到的最大数值
    private int perLine; // 每行显示算式数量
    private Set<String> exercises; // 存储生成的算式，避免重复

    public MathExercises05(int exerciseCount, int maxNumber, int perLine) {
        this.exerciseCount = exerciseCount;
        this.maxNumber = maxNumber;
        this.perLine = perLine;
        this.exercises = new HashSet<>();
    }

    /***********************************************\
     Function Name:
            printHeader
     Function Description:
            Print the header of the system
     Arguments:
            [No arguments]
     Return Value:
            void - This function does not return any value
     History:
            Created on 2024/9/22 by 2928866205@qq.com
     \**********************************************/

    public void printHeader() {

        System.out.println("欢迎使用加减法口算练习系统！");
    }

    /***********************************************\
     Function Name:
            generateEquations
     Function Description:
            Record the calculated equation generated
     Arguments:
            [No arguments]
     Return Value:
            void - This function does not return any value
     History:
            Created on 2024/9/22 by 2928866205@qq.com
     \**********************************************/

    public void generateEquations() {  //负责调用、记录生成的算式
        Random random = new Random(); // 随机数生成器
        int addCount = 0; // 记录加法算式的数量
        int subCount = 0; // 记录减法算式的数量

        // 循环生成算式直到达到要求数量
        while (exercises.size() < exerciseCount) {
            String exercise = generateRandomEquation(random, addCount, subCount);
            if (exercise != null) { // 如果生成的算式有效
                exercises.add(exercise); //把生成的算式加入集合中
                if (exercise.contains("-")) {
                    subCount++;
                } else {
                    addCount++;
                }
            }
        }
    }

    /***********************************************\
     Function Name:
            generateRandomEquation
     Function Description:
            Generates a single random math exercise
            either as an addition or subtraction problem.
            Balances the count of addition and subtraction
            exercises to meet specified proportions.
     Arguments:
            [IN] Random random - A Random object used to generate random numbers
            [IN] int addCount - Current count of addition exercises generated
            [IN] int subCount - Current count of subtraction exercises generated
     Return Value:
            String - A formatted string representing a math exercise,
                     or null if no valid exercise is generated
     History:
            Created on 2024/9/22 by 2928866205@qq.com
     \**********************************************/

    //生成单个随机练习题
    private String generateRandomEquation(Random random, int addCount, int subCount) {
        int num1 = random.nextInt(maxNumber) + 1;
        int num2 = random.nextInt(maxNumber) + 1;
        int operation = random.nextInt(2);

        if (operation == 0 && subCount < exerciseCount / 2) {
            if (num1 < num2) {
                int temp = num1;
                num1 = num2;
                num2 = temp;
            }   //确保结果为正
            return formatEquation(num1," - " ,num2, " = ", num1 - num2);
        } else if (addCount < exerciseCount / 2) {
            num2 = Math.min(num2, maxNumber - num1); //确保结果不超过maxNumber
            return formatEquation(num1," + " ,num2, " = ", num1 + num2);
        }
        return null; //如果生成的算式无效，返回null
    }

    /***********************************************\
     Function Name:
            formatEquation
     Function Description:
            Formats a math equation string with the given components.
     Arguments:
            [IN] int num1 - The first number in the equation
            [IN] String operator - The operator (+ or -)
            [IN] int num2 - The second number in the equation
            [IN] String equal - The equal sign (=)
            [IN] int result - The result of the equation
     Return Value:
            String - A formatted string representing a math equation
     History:
            Created on 2024/9/22 by 2928866205@qq.com
     \**********************************************/

    //格式化算式字符串
    public String formatEquation(int num1, String operator, int num2, String equal, int result) {
        return String.format("%3d%s%3d%s%3d", num1, operator, num2, equal, result);
    }

    //打印练习题
    public void printExercises() {
        int lineCount = 0;  //记录当前行打印的练习题数量
        for (String exercise : exercises) { // 遍历集合中的每一个算式
            if (lineCount > 0 && lineCount % perLine == 0) {
                System.out.println();
            }
            System.out.print(exercise + "    ");
            lineCount++;
        }
        System.out.println();  // Ensure there is a line break at the end
    }

    /***********************************************\
     Function Name:
            printCalculations
     Function Description:
            Prints the total number of exercises generated.
     Arguments:
            [No arguments]
     Return Value:
            void - This function does not return any value
     History:
            Created on 2024/9/22 by 2928866205@qq.com
     \**********************************************/
    // 打印生成的练习题总数
    public void printCalculations() {
       System.out.println("\n 本次共生成" + exercises.size() + "个加减法算式，请认真完成！");
    }

    /***********************************************\
     Function Name:
            main
     Function Description:
            The entry point of the application. This method creates
            an instance of MathExercises05,generates math exercises
            and prints the exercises, and displays the total count of exercises generated.
     Arguments:
            [IN] String[] args - The argument array passed from the
                            command line (not used in this method)
     Return Value:
            void - This function does not return any value
     History:
            Created on 2024/9/22 by 2928866205@qq.com
     \**********************************************/
    public static void main(String[] args) {
        // 创建对象
        MathExercises05 exercises = new MathExercises05(50, 100, 5);
        // 调用方法
        exercises.printHeader();
        exercises.generateEquations();
        exercises.printExercises();
        exercises.printCalculations();
    }
}